package com.lab.idea.bl.pool;

import cn.hutool.core.util.StrUtil;
import com.lab.idea.common.exception.LabException;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ConcurrentHashMap;

/**
 * 线程池
 * @author mao
 */
@Slf4j
public class LabThreadPoolHelper {

    /**
     * 线程池对象
     */
    private static final ConcurrentHashMap<String, LabThreadPoolExecutor> POOL_EXECUTOR = new ConcurrentHashMap<>();

    /**
     * 启动线程池
     * @param threadPool     队列
     */
    public synchronized static void start(LabThreadPool threadPool){
        if (POOL_EXECUTOR.containsKey(threadPool.getPoolName())) {
            return;
        }
        POOL_EXECUTOR.put(threadPool.getPoolName(),new LabThreadPoolExecutor(threadPool));
        log.info("启动线程池:{}", threadPool.getPoolName());
    }


    /**
     * 停止线程池
     * @param threadPool     任务对象
     */
    public synchronized static void stop(LabThreadPool threadPool){
        if (!POOL_EXECUTOR.containsKey(threadPool.getPoolName())) {
            return;
        }
        LabThreadPoolExecutor labThreadPoolExecutor = POOL_EXECUTOR.get(threadPool.getPoolName());
        labThreadPoolExecutor.shutdown();
        POOL_EXECUTOR.remove(threadPool.getPoolName());
        log.info("停止线程池:{}", threadPool.getPoolName());
    }

    /**
     * 更新线程池
     * @param threadPool     任务对象
     */
    public synchronized static void update(LabThreadPool threadPool){
        if (!POOL_EXECUTOR.containsKey(threadPool.getPoolName())) {
            return;
        }
        LabThreadPoolExecutor executor = POOL_EXECUTOR.get(threadPool.getPoolName());
        executor.update(threadPool);
        log.info("更新线程池:{}", threadPool.getPoolName());
    }

    /**
     * 线程池状态
     * @param threadPool     任务对象
     */
    public synchronized static void printState(LabThreadPool threadPool){
        if (!POOL_EXECUTOR.containsKey(threadPool.getPoolName())) {
            return;
        }
        LabThreadPoolExecutor executor = POOL_EXECUTOR.get(threadPool.getPoolName());
        log.warn(LabThreadPrintHelper.format(String.format("线程[%s]状态",threadPool.getPoolName()),executor.getStatus()));
    }

    /**
     * 匹配执行队列
     * @param poolName 线程池名称
     * @return         线程池对象
     */
    public static LabThreadPoolExecutor matcQueue(String poolName) {
        if (POOL_EXECUTOR.containsKey(poolName)) {
            return POOL_EXECUTOR.get(poolName);
        }
        throw new LabException("未匹配到执行队列");
    }

    /**
     * 任务添加
     * @param threadPool    线程池
     * @param command       执行
     */
    public static boolean addTask(LabThreadPool threadPool,Runnable command) {
        if (threadPool == null || StrUtil.isBlankIfStr(threadPool.getPoolName()) || command == null){
            return false;
        }
        // 启动线程池，若已启动则更新
        start(threadPool);
        LabThreadPoolExecutor executor = matcQueue(threadPool.getPoolName());
        try {
            executor.execute(command);
            return true;
        } catch (Exception e) {
            log.error("任务添加失败:{}",threadPool.getPoolName(),e);
            log.warn(LabThreadPrintHelper.format(String.format("线程[%s]状态",threadPool.getPoolName()),executor.getStatus()));
        }
        return false;
    }
}
